﻿using Ex1.School;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Moq;
using System.Collections.Generic;

namespace Ex2.TestSchool
{
    [TestClass()]
    public class CourseTest
    {

        internal virtual IExamResults AddExamResult()
        {
            var mock = new Mock<IExamResults>();
            mock.Setup(x => x.AddExamResult(null, Exams.Informatics, 6)).
                Throws(new ArgumentNullException("Student can't be null!"));

            return mock.Object;
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentNullException), "Student can't be null!")]
        public void AddExamResultTest()
        {
            IExamResults results = AddExamResult();
            Student student = null;
            Exams exam = Exams.Informatics;
            double grade = 6;
            results.AddExamResult(student, exam, grade);
        }

        internal virtual IExamResults GetExamResults()
        {
            var mock = new Mock<IExamResults>();
            mock.Setup(x => x.GetExamResults(null)).
                Throws(new ArgumentNullException());

            return mock.Object;
        }

        [TestMethod()]
        [ExpectedException(typeof(ArgumentNullException), "Student can't be null!")]
        public void GetExamResultsTest()
        {
            IExamResults results = GetExamResults();
            Student student = null;
            results.GetExamResults(student);
        }

        [TestMethod]
        public void CourseConstructorTest()
        {
            Course target = new Course();
            Assert.IsNotNull(target);
        }

        [TestMethod]
        public void AddStudentTest()
        {
            Course target = new Course();
            Student student = new Student("Pesho", 60123);
            target.AddStudent(student);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException), "Limit of course is reached!")]
        public void MaxCourseCapacityReached()
        {
            Course target = new Course();
            for (int i = 0; i < 30; i++)
            {
                Student newStudent = new Student("Pesho" + i, 60000 + i);
                target.AddStudent(newStudent);
            }

            Student oneTooMoreStudent = new Student("Karyk", 10000);
            target.AddStudent(oneTooMoreStudent);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException), "Student already exists!")]
        public void AddOneStudentTwice()
        {
            Course target = new Course();
            Student newStudent = new Student("Pesho", 98765);
            target.AddStudent(newStudent);
            target.AddStudent(newStudent);
        }

        [TestMethod()]
        [ExpectedException(typeof(NullReferenceException), "Student is null!")]
        public void RemoveNullStudentTest()
        {
            Course target = new Course();
            Student student = null;
            target.RemoveStudent(student);
        }

        [TestMethod()]
        [ExpectedException(typeof(InvalidOperationException), "Student is not in the class!")]
        public void RemoveNotExistingStudentTest()
        {
            Course target = new Course();
            Student student = new Student("Pesho", 54123);
            target.RemoveStudent(student);
        }

        [TestMethod()]
        public void RemoveStudentTest()
        {
            Course target = new Course();
            Student student = new Student("Pesho", 54156);
            target.AddStudent(student);
            target.RemoveStudent(student);
        }
    }
}
